﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

namespace nhCore
{
    /// <summary>
    /// 传感器实时数据临时保存及定时存入数据库
    /// </summary>
    public class RealData
    {
        /// <summary>
        /// 保存间隔秒数
        /// </summary>
        public int SaveInterval { get; set; } = 60;
        private IDB Database { get; set; }

        private DicEnvStat DicEnvStat { get; set; }

        /// <summary>
        /// 设备地址对应的实时数据
        /// </summary>
        private Dictionary<byte, Weathers> DicAddrWeathers { get; set; } = new Dictionary<byte, Weathers>();

        /// <summary>
        /// 返回查找到的气象数据，没有则新建空数据
        /// </summary>
        /// <param name="address"></param>
        /// <returns></returns>
        public Weathers FindOrAddWeathers(byte address)
        {
            Weathers weathers;
            if (DicAddrWeathers.ContainsKey(address))
            {
                weathers = DicAddrWeathers[address];
            }
            else
            {
                weathers = new Weathers()
                {
                    Address = address
                };
                DicAddrWeathers.Add(address, weathers);
            }
            return weathers;
        }

        /// <summary>
        /// 读出实时数据
        /// </summary>
        /// <param name="address">设备地址</param>
        /// <returns>气象数据</returns>
        public Weathers ReadWeathers(byte address)
        {
            Weathers weathers = null;
            if (DicAddrWeathers.ContainsKey(address))
            {
                weathers = DicAddrWeathers[address];
            }
            return weathers;
        }

        /// <summary>
        /// 声明一个私有的构造方法，让外部无法调用这个类的构造方法 
        /// </summary>
        /// <param name="database"></param>
        /// <param name="saveInterval"></param>
        private RealData(IDB database, DicEnvStat dicEnvStat, int saveInterval = 10)
        {
            Database = database;
            DicEnvStat = dicEnvStat;
            SaveInterval = saveInterval;

            System.Timers.Timer timer = new System.Timers.Timer(1000);
            timer.Elapsed += OnTimerSave;
            timer.AutoReset = true;
            timer.Enabled = true;
        }

        /// <summary>
        /// 每秒运行一次，超时数据请空，到时保存历史数据
        /// </summary>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void OnTimerSave(object source, System.Timers.ElapsedEventArgs e)
        {
            DateTime now = e.SignalTime;
            foreach (var ws in DicAddrWeathers.Values)
            {
                if (DicEnvStat.EnvStats[ws.Address].IsCgq && now - ws.UpdateTime > CoreGlobal.OutTime)//超时清空数据
                {
                    foreach (var w in ws.Values.Values)
                    {
                        w.Value = null;
                        w.StrValue = "-";
                    }
                }
            }
            if ((now.Minute * 60 + now.Second) % SaveInterval == 0)
            {
                foreach (var ws in DicAddrWeathers.Values)
                {
                    if (DicEnvStat.EnvStats[ws.Address].IsCgq)
                    {
                        //时间为整秒
                        ws.Values[-1].Value = now.AddMilliseconds(-now.Millisecond).Ticks;//传感器时间key为-1
                        Database.SaveHistory(ws);
                    }
                }
            }
        }

        #region 单例模式  
        private static RealData _nhRealData;

        /// <summary>
        /// 返回对象单例
        /// </summary>
        public static RealData Singleton(IDB database = null, DicEnvStat dicEnvStat = null)
        {
            if (_nhRealData == null)
            {
                _nhRealData = new RealData(database, dicEnvStat);
            }

            return _nhRealData;
        }
        #endregion
    }
}
